#include "global.h"
//#include <SimpleMap.h>
#include "ESP32Time.h"
#include "utils.h"
#include "blefunc.h"

RTC_DATA_ATTR int AppMode = 1;
RTC_DATA_ATTR int isActiveValue = 0; // 1,激活2，未激活
bool sendActive = false;
bool connectWifi = false;
static bool isSendDataVal = false;
bool isWiFiConnectedBool = false;
bool isAllowUpgradeValue = false;
bool isRebootVal=false;
bool isSendPingVal = false;
bool isSendNoticeVal = true;
bool isAppReadyVal = false;

bool isSendDataFailedVal = false;

extern ESP32Time rtc;

TimerAction *globalTimerAction;

LocalConfig *globalLocalConfig;

SimpleMap<String, RemoteBle *> *remoteBleMap;
SimpleMap<String, RemoteBleData*> *remoteBleDataMap;

const int MAX_CALLBACK__COUNT = 30;
const int MAX_BTDEVICE_COUNT = 10;

FuncCallBackStruct1 *funcallbacks[MAX_CALLBACK__COUNT]; // 最多20个

FuncCallBackStruct *timercallbacks[MAX_CALLBACK__COUNT]; // 最多20个

FuncCallBackStruct1 *timercallbacks1[MAX_CALLBACK__COUNT]; // 最多20个

 RemoteBle *btDeviceList[MAX_BTDEVICE_COUNT];

const int MAX_INTERLACTION_COUNT = 10;

// 记录上次action发生的时间
RTC_DATA_ATTR B gloablInterValAction[MAX_INTERLACTION_COUNT];
//RTC_DATA_ATTR B gloablWeekAction[7][MAX_INTERLACTION_COUNT];



String deviceType;

long  gSleepDelayTime=0;


// SimpleMap<String, > *funcCallbackMap =  new  SimpleMap<String,void(*)()> ();

bool addGlobalFuncCallBack(String key, FuncCallBack1 fcb)
{
    //  funcCallbackMap->put(key,fcb);
    FuncCallBackStruct1 *func = new FuncCallBackStruct1();
    func->callback = fcb;
    func->key = key;
    for (size_t i = 0; i < MAX_CALLBACK__COUNT; i++)
    {
        if (funcallbacks[i] == NULL)
        {
            funcallbacks[i] = func;
            return true;
        }
    }
    return false;
}

void removeGlobalFuncCallBack(String key)
{
    //  funcCallbackMap->remove(key);
    for (size_t i = 0; i < MAX_CALLBACK__COUNT; i++)
    {
        if (funcallbacks[i] != NULL && funcallbacks[i]->key.equals(key))
        {
            delete funcallbacks[i];
            funcallbacks[i] = nullptr;
        }
    }
}

FuncCallBack1 getGlobalFuncCallBack(String key)
{
    for (size_t i = 0; i < MAX_CALLBACK__COUNT; i++)
    {
        if (funcallbacks[i] != NULL && funcallbacks[i]->key.equals(key))
        {
            return funcallbacks[i]->callback;
        }
    }

    return nullptr;
}

bool addGlobalTimerCallBack(String key, FuncCallBack fcb)
{
    //  funcCallbackMap->put(key,fcb);
    removeGlobalTimerCallBack(key);
    FuncCallBackStruct *func = new FuncCallBackStruct();
    func->callback = fcb;
    func->key = key;
    for (size_t i = 0; i < MAX_CALLBACK__COUNT; i++)
    {
        if (timercallbacks[i] == NULL)
        {
            timercallbacks[i] = func;
            return true;
        }
    }
    return false;
}

void removeGlobalTimerCallBack(String key)
{
    //  funcCallbackMap->remove(key);
    for (size_t i = 0; i < MAX_CALLBACK__COUNT; i++)
    {
        if (timercallbacks[i] != NULL && timercallbacks[i]->key.equals(key))
        {
            delete timercallbacks[i];
            timercallbacks[i] = nullptr;
        }
    }
}


 
void removeGlobalTimerCallBack1(String key)
{
    //  funcCallbackMap->remove(key);
    for (size_t i = 0; i < MAX_CALLBACK__COUNT; i++)
    {
        if (timercallbacks1[i] != NULL && timercallbacks1[i]->key.equals(key))
        {
            delete timercallbacks1[i];
            timercallbacks1[i] = nullptr;
        }
    }
}

bool addGlobalTimerCallBack1(String key, FuncCallBack1 fcb)
{
    //  funcCallbackMap->put(key,fcb);
    removeGlobalTimerCallBack1(key);
    FuncCallBackStruct1 *func = new FuncCallBackStruct1();
    func->callback = fcb;
    func->key = key;
    for (size_t i = 0; i < MAX_CALLBACK__COUNT; i++)
    {
        if (timercallbacks1[i] == NULL)
        {
            timercallbacks1[i] = func;
            return true;
        }
    }
    return false;
}

 



FuncCallBack getTimerCallBack(String key)
{
    for (size_t i = 0; i < MAX_CALLBACK__COUNT; i++)
    {
        if (timercallbacks[i] != NULL && timercallbacks[i]->key.equals(key))
        {
            return timercallbacks[i]->callback;
        }
    }

    return nullptr;
}

void setGlobalTimerAction(TimerAction *ta)
{
    globalTimerAction = ta;
}


//将上次action 的时间从RTC中读出并存储到本地内存
void setGlobalRTCIntervalAciton()
{
    TimerAction *action = getGlobalTimerAction();
    if (action == nullptr)
    {
        return;
    }
    for (size_t i = 0; i < action->intervalActionCount; i++)
    {
        if (action->intervalTimerAction[i]->action == nullptr)
        {
            continue;
        }
        // String id = action->intervalTimerAction[i]->action->id;
        // id.toCharArray(gloablInterValAction[i].id, id.length() + 1);
        gloablInterValAction[i].time = rtc.getEpoch();
    }
}

TimerAction *getGlobalTimerAction()
{
    return globalTimerAction;
}

void deleteGlobalTimerAction()
{
    Serial.println("deleteGlobalTimerAction  地址： ");
    Serial.println((long)globalTimerAction);
    if (globalTimerAction != nullptr)
    {
        delete globalTimerAction;
        globalTimerAction =nullptr;
    }
}

void setGlobalLocalConfig(LocalConfig *ta)
{
    globalLocalConfig = ta;
}
LocalConfig *getGlobalLocalConfig()
{
    if (globalLocalConfig == nullptr)
    {
        globalLocalConfig = new LocalConfig();
    }
    return globalLocalConfig;
}

void deleteGlobalLocalConfig()
{
    if (globalLocalConfig != nullptr)
    {
        delete globalLocalConfig;
    }
}

void setNeedConnectWiFi(bool b)
{
    connectWifi = b;
}

void setNeedSendActive(bool b)
{
    sendActive = b;
}
bool isNeedConnectWiFi()
{
    return connectWifi;
}
bool isNeedSendActive()
{
    return sendActive;
}

bool isWiFiConnected()
{
    return isWiFiConnectedBool;
}
void setWiFiConnected(bool b)
{
    isWiFiConnectedBool = b;
}

B getB(String id)
{

    for (size_t i = 0; i < MAX_INTERLACTION_COUNT; i++)
    {
        if (id.equals(gloablInterValAction[i].id))
        {
            return gloablInterValAction[i];
        }
    }

    B b;
    return b;
}

bool isAllowOfflineRun()
{
    if (getGlobalLocalConfig() == nullptr || getGlobalLocalConfig()->getTypeConfig() == nullptr)
    {
        return false; // 默认不允许离线运行
    }
    return getGlobalLocalConfig()->getTypeConfig()->getAllowOffLineRun();
}

int getAppMode()
{

   // return 1;
    if (getGlobalLocalConfig() == nullptr 
    || getGlobalLocalConfig()->getTypeConfig() == NULL
    || getGlobalLocalConfig()->getTypeConfig() == 0)
    {
            printStr("getGlobalLocalConfig()");
        return 1; // 性能模式
    }
 
    return getGlobalLocalConfig()->getTypeConfig()->getRunMode();
}

void setAppMode(int mode)
{
    if (getGlobalLocalConfig() == nullptr || getGlobalLocalConfig()->getTypeConfig() == nullptr)
    {
        return;
    }

    return getGlobalLocalConfig()->getTypeConfig()->setRunMode(mode);
}

bool isActive()
{
    if (isActiveValue == 0)
    {

        String value = getPreferenceString("isActive");
        if (!value.isEmpty())
        {
            isActiveValue = value.toInt();
        }
    }

    return isActiveValue == 1;
}

void setActive(bool b)
{

    isActiveValue = b ? 1 : 2;

    putPreferenceString("isActive", String(isActiveValue));
}

void setTimerWakeup(String second)
{
    
     getGlobalLocalConfig()->getTypeConfig()->setWakeupInterval(second);
}

long getTimerWakeup()
{

   return   getGlobalLocalConfig()->getTypeConfig()->getWakeupInterval();
  
 
}



FuncCallBack delayCallBack;
long delayTime=0;

void delayCount(String s){
    long i = s.toInt();
    if(i>=delayTime){
        if(delayCallBack!=nullptr){
            delayCallBack(s);
        }

        removeGlobalTimerCallBack("delayExcute");
    }
}
bool excuteDelay(long delay, FuncCallBack callback)
{
    delayTime = delay;
    delayCallBack = callback;
    removeGlobalTimerCallBack("delayExcute");

     bool  result =  addGlobalTimerCallBack("delayExcute", delayCount);

     if(result){
      //  Serial.println("添加 delay 成功");
     }else{
          Serial.println("添加 delay 失败");
     }

     return result;//一定要有返回值
}

bool excuteDelay(long delay, String id, FuncCallBack callback)
{
    delayTime = delay;
    delayCallBack = callback;

   bool  isSuccess = id.concat("delayExcute");
   if(!isSuccess){
        printStr("isSuccess = id.concat(delayExcute) 失败");
   }

    removeGlobalTimerCallBack(id);

     bool  result =  addGlobalTimerCallBack(id, delayCount);

     if(result){
      //  Serial.println("添加 delay 成功");
     }else{
          Serial.println("添加 delay 失败");
     }

     return result;//一定要有返回值
}

  void cancelExcuteDelay(String id){
       id.concat("delayExcute");
      removeGlobalTimerCallBack(id);
  }

 bool isHasUpgrade(){

     TypeConfig* typeConfig =  getGlobalLocalConfig()->getTypeConfig();
     if(typeConfig!=nullptr){
        if( typeConfig->getUpdateFirmware()&&(!isStringEmpty(typeConfig->getFirmwareUrl()))){
            return true;
        }
     }

     return false;
 }

  bool isAllowUpgrade(){
    return isAllowUpgradeValue;
  }


   void setAllowupgrade(bool b){
    isAllowUpgradeValue = b;
   }
 void setDeviceType(String deviceTypeVal){
    deviceType = deviceTypeVal;
 }
 
 String getDeviceType(){
    return deviceType;
 }


//是否需要重启标志
 bool isReboot(){
    return isRebootVal;
 }

 void setReboot(bool val){
    isRebootVal = val;
 }

 void setSendPing(bool b){
    isSendPingVal = b;
 }

 bool isSendPing(){
    return isSendPingVal;
 }
void setSendData(bool b){
   isSendDataVal = b;
}
bool isSendData(){
    return isSendDataVal;
}


bool isSendDataFailed(){
    return isSendDataFailedVal;
}
void setSendDataFailed(bool b){
    isSendDataFailedVal = b;
}


bool isSendNotice(){
    return isSendNoticeVal;
}

bool isAppReady(){
    return isAppReadyVal;
}

void setAppReady(bool b){
    isAppReadyVal = b;
}


void setGlobalSleepdelayTime(long time){
  gSleepDelayTime = time;
}

long getGlobalSleepdelayTime(){
    return gSleepDelayTime;
}

SimpleMap<String,RemoteBle*>* getRemoteBleMap(){

  if (remoteBleMap != nullptr)
  {
    return remoteBleMap;
  }
  remoteBleMap = new SimpleMap<String, RemoteBle *>([](String &a, String &b) -> int
                                                    {
        if (a == b) return 0;
        if (a > b) return 1;
        /*if (a < b) */ return -1; });



  return remoteBleMap;
}


SimpleMap<String,RemoteBleData*>* getRemoteBleDataMap(){

  if (remoteBleDataMap != nullptr)
  {
    return remoteBleDataMap;
  }
  remoteBleDataMap = new SimpleMap<String, RemoteBleData*>([](String &a, String &b) -> int
        {
        if (a == b) return 0;
        if (a > b) return 1;
        /*if (a < b) */ return -1; });
  return remoteBleDataMap;
}